package com.minivision.fdiot.aspect;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.minivision.fdiot.annotation.Log;
import com.minivision.fdiot.common.CommonConstants;
import com.minivision.fdiot.common.RestResult;
import com.minivision.fdiot.entity.OpLog;
import com.minivision.fdiot.service.OpLogService;
import com.minivision.fdiot.util.ParamUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 用于记录操作日志的切面
 * @author hughzhao
 * @2017年5月22日
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

  @Autowired
  private OpLogService opLogService;
  
  @Autowired
  private ObjectMapper mapper;

  /**
   * 记录操作日志
   * @param joinPoint
   * @param log
   * @param retVal
   * @throws Throwable
   */
  @AfterReturning(pointcut = "@annotation(com.minivision.fdiot.annotation.Log) && @annotation(logAnno)", returning="retVal")
  public void doLog(JoinPoint joinPoint, Log logAnno, Object retVal) throws Exception {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();

    //请求URL
    String url = request.getRequestURL().toString();
    //请求参数
    String paramString = ParamUtils.getParamString(request);
    //请求IP
    String ip = request.getRemoteAddr();
    // save in DB
    OpLog opLog = new OpLog();
    opLog.setIp(ip);
    opLog.setModule(logAnno.module());
    opLog.setOperation(logAnno.operation());
    opLog.setRequest(request.getMethod() + " " + url + ":" + (logAnno.ignoreArgs() ? "" : paramString));
    opLog.setResponse(retVal instanceof RestResult<?> ? mapper.writeValueAsString(retVal) : (retVal instanceof String ? (String) retVal : ""));
    String requestTxt = opLog.getRequest();
    String responseTxt = opLog.getResponse();
    //限定存储字段长度
    if (requestTxt.length() > CommonConstants.OPLOG_DATA_LIMIT) {
      opLog.setRequest(requestTxt.substring(0, CommonConstants.OPLOG_DATA_LIMIT));
    }
    if (responseTxt.length() > CommonConstants.OPLOG_DATA_LIMIT) {
      opLog.setResponse(responseTxt.substring(0, CommonConstants.OPLOG_DATA_LIMIT));
    }

    try {
      opLogService.create(opLog);
    } catch (Exception e) {
      log.error("save oplog exception", e);
    }
  }

}
